﻿SSVC.Utils.Page.IncludeFile("../styles/Feed.css", "css");

SSVC.Wrap.Dojo.Require([
    "dojo/_base/fx",
    "dojo/_base/lang",
    "dojo/dom-style",
    "dojo/mouse",
    "dojo/on",
	"dijit/layout/ContentPane",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dojo/text!../scripts/Feed.html"],

	 SSVC.Wrap.Dojo.Hitch(this,
		function(baseFx, lang, domStyle, mouse, on, ContentPane, _WidgetBase, _TemplatedMixin, template)
		{
			var currentFeed = null;
			var aras = top.aras;
			var currentPage = 1;
			var self = null;
			var basicFeedTitle = "Secure Social Feed";

			SSVC.Wrap.Dojo.Declare("Feed", [_WidgetBase, _TemplatedMixin, SSVC.UI.TemplateControl], {
				templateString: template,
				replyToMessageId: null,
				selectedMessageId: null,
				msgStructure: null,
				FeedToolbar: null,
				ReplyToolbar: null,
				FilterPopup: null,
				UserControl: null,
				ShowMoreMessagesButton: null,
				CurrentSortingMode: null,
				CurrentDisplayMode: null,
				levelIndent: null,
				InstanceItemId: null,
				TopMost: null,
				CurrentIdentity: null,
				FilterMessagesButtonLabel: SSVC.Utils.GetResource("feed_show_all_messages"),

				ContextMessageList: null,

				SecureMessage: null,

				itemXPath: "",

				filterArr: null,//array filter = [{name:value, text:value, condition:value}...]

				constructor: function()
				{
					self = this;
					this.levelIndent = 30;
					this.newMessageList();
					this.CurrentIdentity = SSVC.ArasHelper.getUserHelper().CurrentIdentity;
				},

				postCreate: function()
				{
					this.inherited(arguments);
					this.FeedToolbar = new SSVC.UI.FeedToolbar(SSVC.VisualCollaborationTool.Preferences.MessageTemplatesArr);
					this.FeedToolbar.OnChangeDisplayMode = this.changeMessageDisplayMode;
					this.FeedToolbar.OnChangeSortingMode = this.changeMessageSortingMode;
					this.FeedToolbar.OnRefreshButtonClick = SSVC.Wrap.Dojo.Hitch(this, "load");
					this.FeedToolbar.OnMoreOptionLinkClick = this.showFilterMoreOptions;
					this.FeedToolbar.OnAddCommentBtnClick = this.onSendCommentEventHandler;
					this.FeedToolbar.OnFilterFeedButtonClick = this.filterByMessageText;
					this.FeedToolbar.OnTextAreaKeyDown = this.onFeedToolbarTextKeyDown;
					this.FeedToolbar.placeAt(this.ToolbarContainer);

					this.CurrentDisplayMode = this.FeedToolbar.GetCurrentDisplayMode();
					this.CurrentSortingMode = this.FeedToolbar.GetCurrentSortingMode();

					this.ReplyToolbar = new SSVC.UI.ReplyToolbar().placeAt(this.ReplyToolbarOuter);
					this.ReplyToolbar.OnReplyTextKeyUp = this.onReplyToolbarReplyTextKeyUp;
					this.ReplyToolbar.OnReplyButtonClick = this.onReplyToolbarReplyButtonClick;

					this.FilterPopup = new SSVC.UI.FilterPopup().placeAt(this.FilteringPopupContainer);
					this.FilterPopup.OnBtnSearchNodeClick = this.executeFilter;
					this.FilterPopup.OnBtnCancelNodeClick = this.cancelFilter;

					this.UserControl = new SSVC.UI.UserControl().placeAt(this.UserInfoContainer);
					this.TopMost = new TopMostMessage(this.MessageContainer);

					this.ShowMoreMessagesButton = new ContentPane({
						region: "bottom",
						id: "ShowMoreMessagesButton",
						"class": "ShowMoreMessagesDiv",
						content: "Show more messages"
					});
					this.own(
						on(this.ShowMoreMessagesButton, "click", lang.hitch(this, "getMoreMessages", false)),
						on(this.UserInfoContainer, "mouseover", lang.hitch(this, "ShowElement", this.UserInfoContainer)),
						on(this.UserInfoContainer, "mouseout", lang.hitch(this, "HideElement", this.UserInfoContainer)),
						on(this.ActualDateTimeContainer, "mouseover", lang.hitch(this, "ShowElement", this.ActualDateTimeContainer)),
						on(this.ActualDateTimeContainer, "mouseout", lang.hitch(this, "HideElement", this.ActualDateTimeContainer)),
						on(this.FilterMessageButton, "click", lang.hitch(this, "filterMessageButton_OnClick")),
						on(this.MessageContainer, "keydown", this.onKeyDownTopMessageMove)
						);

					this.TopMost.moveHome();
				},

				//Feed methods:

				load: function()
				{
					SSVC.ArasHelper.getUserHelper().UpdateOnlineUsers();

					self.SecureMessage = self.getMessagesFromServer(self.filterArr);
					self.SecureMessage.sort(self.CurrentSortingMode);

					if (self.filterArr)
						self.ContextMessageList = SSVC.Message.toMessageArr(self.SecureMessage.itemStructure);
					else
						self.MessageList = SSVC.Message.toMessageArr(self.SecureMessage.itemStructure);

					self.addMessagesToFeed(self.getCurrentMessageList(), true);
				},

				getMessagesFromServer: function(filter)
				{
					var itms = new SSVC.ArasHelper.SecureMessage("get");
					itms.setPropertyAttribute("parent_id", "condition", "is null");
					itms.setAttribute("select", "classification, parent_id, message_text, from_identity, to_identity, sent, thumbnail, snapshot, source_major_rev, source_generation, source_state, source_id, markup, history_item, last_reply_sent, children_count, view_state");
					itms.setAttribute("page", currentPage);
					itms.setAttribute("pagesize", 25);
					itms.setAttribute("orderBy", "sent desc");
					if (filter)
						itms.applyFilter(filter);
					itms.fill();
					itms.buildStructure(true, 3);

					return itms;
				},

				getRepliesMessagesFromServer: function(parentID)
				{
					var itms = new SSVC.ArasHelper.SecureMessage("get");
					itms.setProperty("parent_id", parentID);
					itms.setAttribute("select", "classification, parent_id, message_text, from_identity, to_identity, sent, thumbnail, snapshot, source_major_rev, source_generation, source_state, source_id, markup, history_item, last_reply_sent, children_count, view_state");
					itms.setAttribute("orderBy", "sent asc");
					itms.fill();
					itms.buildStructure(false);

					return itms;
				},

				getMoreMessages: function()
				{
					currentPage++;

					var newItms = self.getMessagesFromServer(self.filterArr);
					var newMess = SSVC.Message.toMessageArr(newItms.itemStructure);
					self.MessageList.PushRange(newMess);
					self.addMessagesToFeed(newMess, null, false);

					if (newItms.itemStructure.length <= 0)
					{
						self.ShowMoreMessagesButton.domNode.innerHTML = SSVC.Utils.GetResource("feed_no_secure_messages");
						currentPage--;
						return;
					}
					if (newItms.itemStructure.length <= 25)
					{
						self.ShowMoreMessagesButton.domNode.innerHTML = SSVC.Utils.GetResource("feed_no_secure_messages");
					}
				},

				addMessagesToFeed: function(messageList, cleanBefore)
				{
					if (cleanBefore)
					{
						this.MessageContainer.innerHTML = "";
						//this.newMessageList();
					}

					this.bindingMessageContainer(messageList, this.MessageContainer);

					var showmorebutton = document.getElementById("ShowMoreMessagesButton");
					if (showmorebutton)
						this.MessageContainer.removeChild(showmorebutton);
					if (this.ShowMoreMessagesButton)
					{
						this.MessageContainer.appendChild(this.ShowMoreMessagesButton.domNode);

						if (this.SecureMessage.itemStructure.length <= 0)
							this.ShowMoreMessagesButton.domNode.innerHTML = SSVC.Utils.GetResource("feed_no_secure_messages");
						else
							this.ShowMoreMessagesButton.domNode.innerHTML = SSVC.Utils.GetResource("feed_show_more_messages");
					}
				},

				newMessageList: function()
				{
					this.SecureMessage = [];
					this.MessageList = [];
				},

				bindingMessageContainer: function(messageList, container)
				{
					SSVC.Wrap.Dojo.Array.forEach(messageList, SSVC.Wrap.Dojo.Hitch(this, function(message)
					{
						this.createMessageControl(message, container, this.CurrentSortingMode === SSVC.Utils.Enums.SortMode.Conversation);

						this.bindingMessageContainer(message.childs, container);
					}));
				},

				createMessageControl: function(message, container, showMessageOnCreation)
				{
					var messageControl;
					// Remove widget with message.messageId before creating new one
					SSVC.Wrap.Dojo.Require(["dijit/registry"], function(registry)
					{
						messageControl = registry.byId(message.messageId);
						if (messageControl)
							messageControl.destroy();
					});

					messageControl = new SSVC.UI.MessageControl(message, SSVC.Utils.isNullOrUndefined(top.instance), showMessageOnCreation);

					//todo: call once
					SSVC.Utils.Page.LoadModules(["ShortenTextWithMore"]);
					// TODO: SSVC.Utils.Shorten() move to   SSVC.UI.MessageControl
					SSVC.Utils.Shorten();
					messageControl.OnShowLinkNodeClick = SSVC.Wrap.Dojo.Partial(this.onChangeFeedContextEventHandler, message.communityId);
					messageControl.KeyedNameNode.addEventListener("click", SSVC.Wrap.Dojo.Partial(this.onShowDocumentEventHandler, message.messageId));
					messageControl.OnUserNameNodeMouseOver = this.showUserInfo;
					messageControl.OnUserNameNodeMouseOut = this.hideUserInfo;
					messageControl.OnDateTimeNodeMouseOver = this.showActualDate;
					messageControl.OnDateTimeNodeMouseOut = this.hideActualDate;
					messageControl.OnReplyClick = this.onClickReplyLinkEventHandler;
					messageControl.OnReplyWithClick = this.onClickReplyWithMarkupLinkEventHandler;
					messageControl.OnDisplayOfRepliesLinkClick = this.showHideReplies;
					if (messageControl.Classification === "Markup")
						messageControl.OnThumbnailNodeClick = SSVC.Wrap.Dojo.Partial(this.onDisplayMarkupEventHandler, message.messageId);

					messageControl.placeAt(container);
					return messageControl;
				},

				isMessagesItmsExist: function(itms)
				{
					if (itms.isError())
					{
						this.ShowMoreMessagesButton.domNode.innerHTML = SSVC.Utils.GetResource("feed_no_secure_messages");
						currentPage--;
						return false;
					}
					return true;
				},

				showHideReplies: function()
				{
					function hideRepliesInner(parentID)
					{
						var parent = self.SecureMessage.itemStructure.Find("id", parentID);
						if (!parent)
							return;

						for (var i = 0; i < parent.childs.length ; i++)
							document.getElementById(parent.childs[i].id).style.display = "none";
					}

					function showRepliesInner(parentID, numberToShow)
					{
						var parent = self.SecureMessage.itemStructure.Find("id", parentID);
						if (!parent)
							return;

						numberToShow = numberToShow || parent.childs.length;

						for (var i = 0; i < numberToShow ; i++)
							document.getElementById(parent.childs[i].id).style.display = "table";
					}

					switch (this.RepliesState)
					{
						case "A1":
							hideRepliesInner(this.id);

							this.RepliesState = "A2";
							this.DisplayOfRepliesLink.innerHTML = SSVC.Utils.GetResource("mc_show_replies");
							break;
						case "A2":
							showRepliesInner(this.id);

							this.RepliesState = "A1";
							this.DisplayOfRepliesLink.innerHTML = SSVC.Utils.GetResource("mc_hide_replies");
							break;
						case "B1":
							var parent = self.SecureMessage.itemStructure.Find("id", this.id);
							if (this.MarkupMessage.childrenCount === parent.childs.length)
							{
								showRepliesInner(this.id);
							}
							else
							{
								var placeAfterID = this.id;
								var container = null;
								SSVC.Wrap.Dojo.Require(["dojo/dom-construct"], function(domConstruct)
								{
									container = domConstruct.place("<div id='tempDiv" + this.id + "'></div>", placeAfterID, "after");
								});

								var allReplies = self.getRepliesMessagesFromServer(this.id).itemStructure;
								var allRepliesMessages = SSVC.Message.toMessageArr(allReplies);

								for (var i = 0; i < allReplies.length; i++)
								{
									var element = document.getElementById(allReplies[i].id);
									if (element)
									{
										placeAfterID = allReplies[i].id;
									}
									else
									{
										self.createMessageControl(allRepliesMessages[i], container, true);
										SSVC.Wrap.Dojo.Require(["dojo/dom-construct"], function(domConstruct)
										{
											domConstruct.place(document.getElementById(allReplies[i].id), placeAfterID, "after");
										});
										placeAfterID = allReplies[i].id;

										if (i < parent.childs.length)
											parent.childs.unshift(allReplies[i]);
										else
											parent.childs.push(allReplies[i]);
									}
								}

								SSVC.Wrap.Dojo.Require(["dojo/dom-construct"], function(domConstruct)
								{
									container = domConstruct.destroy("tempDiv" + this.id);
								});
							}

							this.RepliesState = "B2";
							this.DisplayOfRepliesLink.innerHTML = SSVC.Utils.GetResource("mc_hide_replies");
							break;
						case "B2":
							hideRepliesInner(this.id);

							this.RepliesState = "B3";
							this.DisplayOfRepliesLink.innerHTML = SSVC.Utils.GetResource("mc_show_replies");
							break;
						case "B3":
							showRepliesInner(this.id, 3);

							this.RepliesState = "B1";
							this.DisplayOfRepliesLink.innerHTML = "{0} ({1})".Format(SSVC.Utils.GetResource("mc_show_all_replies"), this.ChildrenCount);
							break;
					}
				},

				update: function()
				{
					this.ReplyToolbar.placeAt(this.ReplyToolbarOuter);

					this.addMessagesToFeed(this.getCurrentMessageList(), true);
				},

				getCurrentMessageList: function()
				{
					if (this.ContextMessageList)
						return this.ContextMessageList;
					else return this.MessageList;
				},

				sendReply: function(message, text)
				{
					if (text.trim() === "")
						return;

					var document = this.SecureMessage.itemStructure.Find("communityId", message.communityId).relatedItm;

					var smProperties = {};
					smProperties.classification = "Comment";
					smProperties.from_identity = this.CurrentIdentity.getID();
					smProperties.message_text = text;
					smProperties.parent_id = message.parentMessageId || message.messageId;
					smProperties.source_id = message.communityId;
					smProperties.source_major_rev = document.getProperty("major_rev", "");
					smProperties.source_generation = document.getProperty("generation", "");
					smProperties.source_state = document.getProperty("state", "");

					var secureMessage = new SSVC.ArasHelper.SecureMessage("add");
					secureMessage.setItemBeforeSaving(smProperties);
					secureMessage.fill();
					secureMessage.buildStructure();

					if (!secureMessage.isError())
						return secureMessage;

					return false;
				},

				sendComment: function(document, text)
				{
					if (text.trim() === "")
						return;

					var smProperties = {};
					smProperties.classification = "Comment";
					smProperties.from_identity = this.CurrentIdentity.getID();
					smProperties.message_text = text;
					smProperties.parent_id = null;
					smProperties.source_id = this.currentCommunityId;
					smProperties.source_major_rev = document.getProperty("major_rev", "");
					smProperties.source_generation = document.getProperty("generation", "");
					smProperties.source_state = document.getProperty("state", "");

					var secureMessage = new SSVC.ArasHelper.SecureMessage("add");
					secureMessage.setItemBeforeSaving(smProperties);
					secureMessage.fill();
					secureMessage.buildStructure();

					if (!secureMessage.isError())
						return secureMessage;

					return false;
				},

				filterByMessageText: function()
				{
					if (self.FeedToolbar.ftFilterByMessageText.value === "Search messages...")
						return;

					self.filterArr =
						[{
							name: "message_text",
							text: "*" + self.FeedToolbar.ftFilterByMessageText.value + "*",
							condition: "like"
						}];

					self.FilteringMessageText.innerHTML = "{0}: \"{1}\"".Format(SSVC.Utils.GetResource("feed_showing_filter_results"), edtFilterbyMessageText.value);

					if (self.FilteringMessageContainer.style.display === "none")
					{
						self.FilteringMessageContainer.style.display = "block";

						var filteringMessageContainerRect = self.FilteringMessageContainer.getBoundingClientRect();

						var topContainerRect = self.TopContainerNode.getBoundingClientRect();
						self.TopContainerNode.style.height = (topContainerRect.height + filteringMessageContainerRect.height) + "px";

						var messageContainerRect = self.MessageContainer.getBoundingClientRect();
						self.MessageContainer.style.height = (messageContainerRect.height - filteringMessageContainerRect.height) + "px";
					}

					self.update();
				},

				executeFilter: function()
				{
					if (!self.FilterPopup.Validate())
						return;

					self.filterArr = self.FilterPopup.ComposeFilterArray();

					self.FilteringPopupContainer.style.display = "none";

					var messageSearch = self.FeedToolbar.ftFilterByMessageText.value.trim();
					if (messageSearch === SSVC.Utils.GetResource("feed_tb_def_message_search"))
						messageSearch = "";
					else
						messageSearch = "\"" + messageSearch + "\",";
					var moreOptionsSearch = self.FilterPopup.GetFilteringMessage().trim();
					if (messageSearch || moreOptionsSearch)
					{
						if (messageSearch === "")
							self.FilteringMessageText.innerHTML = "{0}: {1}".Format(SSVC.Utils.GetResource("feed_showing_filter_results"), moreOptionsSearch);
						else
							self.FilteringMessageText.innerHTML = "{0}: {1} {2}".Format(SSVC.Utils.GetResource("feed_showing_filter_results"), messageSearch, moreOptionsSearch);
						self.FilteringMessageContainer.style.display = "block";

						var filteringMessageContainerRect = self.FilteringMessageContainer.getBoundingClientRect();

						var topContainerRect = self.TopContainerNode.getBoundingClientRect();
						self.TopContainerNode.style.height = (topContainerRect.height + filteringMessageContainerRect.height) + "px";

						var messageContainerRect = self.MessageContainer.getBoundingClientRect();
						self.MessageContainer.style.height = (messageContainerRect.height - filteringMessageContainerRect.height) + "px";
					}

					self.update();
				},

				cancelFilter: function()
				{
					self.FilteringPopupContainer.style.display = "none";
				},

				onClickClearFilter: function()
				{
					var filteringMessageContainerRect = self.FilteringMessageContainer.getBoundingClientRect();

					self.FilteringMessageContainer.style.display = "none";

					var topContainerRect = self.TopContainerNode.getBoundingClientRect();
					self.TopContainerNode.style.height = (topContainerRect.height - filteringMessageContainerRect.height) + "px";

					var messageContainerRect = self.MessageContainer.getBoundingClientRect();
					self.MessageContainer.style.height = (messageContainerRect.height + filteringMessageContainerRect.height) + "px";

					self.FilterPopup.ResetFields();

					self.filterArr = [];
					self.update();
				},

				getDisplayMode: function()
				{
					return this.FeedToolbar.ftDisplayModeSelector.value;
				},

				updateFeedSize: function()
				{
					//messageTopContainer.style.height = this.getMessageContainerHeight() + 'px';
					if (whereUsed === "MainWindow")
					{
						snapshotContainer.style.height = this.getSnapshotContainerHeight() + "px";
						snapshotContainer.style.width = snapshotTopContainer.clientWidth + "px";
					}
				},

				onHideActualDateEventHandler: function()
				{
					actualDateTimeContainer.style.display = "none";
				},

				showFilterMoreOptions: function()
				{
					if (self.FilteringPopupContainer.style.display !== "none")
					{
						self.FilteringPopupContainer.style.display = "none";
						return;
					}

					var feedContainerRect = self.FeedToolbar.domNode.getBoundingClientRect();
					var moreOptionsRect = this.MoreOptionLink.getBoundingClientRect();

					self.FilteringPopupContainer.style.left = (feedContainerRect.left + feedContainerRect.width - 320) + "px";
					self.FilteringPopupContainer.style.top = (moreOptionsRect.top + moreOptionsRect.height + 5) + "px";
					self.FilteringPopupContainer.style.display = "inline";
				},

				getFirstFoundPdfDocumentFromDocument: function(docId)
				{
					//Get current document with the first found pdf file
					var aml =
							"<AML>" +
								"<Item type='Document' action='get' id='" + docId + "'>" +
									"<Relationships>" +
										"<Item type='Document File' action='get' orderBy='sort_order' maxRecords='1'>" +
											"<related_id>" +
												"<Item type='File' action='get'>" +
													"<file_type>" +
														"<Item type='FileType' action='get'>" +
															"<extension>pdf</extension>" +
														"</Item>" +
													"</file_type>" +
												"</Item>" +
											"</related_id>" +
										"</Item>" +
									"</Relationships>" +
								"</Item>" +
							"</AML>";

					var documentItem = top.aras.newIOMItem("Document");
					documentItem.loadAML(aml);
					documentItem = documentItem.apply();

					if (documentItem.isError())
					{
						return;
					}

					//Get first found pdf file
					var fileItem = documentItem.getItemsByXPath("Relationships/Item/related_id/Item");

					if (fileItem.getItemCount() === 0)
					{
						//No pdf file was found
						//top.aras.AlertError(SSVC.Utils.GetResource("feed_pdf_not_found"));
						return;
					}

					var fileId = fileItem.getID();
					var fileUrl = top.aras.IomInnovator.getFileUrl(fileId, top.aras.Enums.UrlType.SecurityToken);

					return {
						fileId: fileId,
						fileUrl: fileUrl,
						fileType: "pdf"
					};
				},

				getFirstFoundImageFromDocument: function(docId)
				{
					//Get current document with the first found pdf file
					var aml =
							"<AML>" +
								"<Item type='Document' action='get' id='" + docId + "'>" +
									"<Relationships>" +
										"<Item type='Document File' action='get' orderBy='sort_order' maxRecords='1'>" +
											"<related_id>" +
												"<Item type='File' action='get'>" +
													"<file_type>" +
														"<Item type='FileType' action='get'>" +
															"<or>" +
																"<extension>png</extension>" +
																"<extension condition='like'>*jpg*</extension>" +
																"<extension>gif</extension>" +
															"</or>" +
														"</Item>" +
													"</file_type>" +
												"</Item>" +
											"</related_id>" +
										"</Item>" +
									"</Relationships>" +
								"</Item>" +
							"</AML>";

					var documentItem = top.aras.newIOMItem("Document");
					documentItem.loadAML(aml);
					documentItem = documentItem.apply();

					if (documentItem.isError())
						return;

					var fileItem = documentItem.getItemsByXPath("Relationships/Item/related_id/Item");

					if (fileItem.getItemCount() === 0)
						return;

					var fileId = fileItem.getID();
					var fileUrl = top.aras.IomInnovator.getFileUrl(fileId, top.aras.Enums.UrlType.SecurityToken);

					return {
						fileId: fileId,
						fileUrl: fileUrl,
						fileType: "image"
					};
				},

				getFirstFoundHwfDocumentFromCAD: function(cadId)
				{
					var cadItem = top.aras.newIOMItem("CAD", "get");
					cadItem.setProperty("id", cadId);
					cadItem = cadItem.apply();

					if (cadItem.getProperty("view_file", "") === "")
					{
						top.aras.AlertError(SSVC.Utils.GetResource("feed_hwf_not_found"));
						return;
					}

					var fileId = cadItem.getProperty("view_file");
					var fileUrl = top.aras.IomInnovator.getFileUrl(fileId, top.aras.Enums.UrlType.SecurityToken);

					return {
						fileId: fileId,
						fileUrl: fileUrl,
						fileType: "hwf"
					};
				},

				// TODO: move to ArasHelper.SecureMessage
				getFirstFoundImageFromPart: function(partId)
				{
					//Get current part with the first found image file
					var aml =
							"<AML>" +
								"<Item type='Part' action='get' id='" + partId + "' select='thumbnail' />" +
							"</AML>";

					var partItem = top.aras.newIOMItem("Part");
					partItem.loadAML(aml);
					partItem = partItem.apply();

					if (partItem.isError())
					{
						return;
					}

					var thumbnailVaultUrl = partItem.getProperty("thumbnail", "");
					var thumbnailId = thumbnailVaultUrl.replace(/vault:\/\/\/\?fileid\=/i, "");

					if (thumbnailId === "")
					{
						//No file was found
						top.aras.AlertError(SSVC.Utils.GetResource("feed_file_not_found"));
						return;
					}

					var imageItm = top.aras.newIOMItem("File", "get");
					imageItm.setID(thumbnailId);
					imageItm = imageItm.apply();

					if (imageItm.isError())
					{
						return;
					}

					var fileName = imageItm.getProperty("filename", "");
					var fileExtension = fileName.split(".").pop();

					var imageExtensionsList = ["png", "jpg", "jpeg", "bmp", "gif", "tif", "tiff", "svg"];

					if (imageExtensionsList.indexOf(fileExtension) === -1)
					{
						//It's not an image
						top.aras.AlertError(SSVC.Utils.GetResource("feed_file_not_image"));
						return;
					}

					var fileUrl = top.aras.IomInnovator.getFileUrl(thumbnailId, top.aras.Enums.UrlType.SecurityToken);

					return {
						fileId: thumbnailId,
						fileUrl: fileUrl
					};
				},

				//Events:
				changeMessageDisplayMode: function()
				{
					self.CurrentDisplayMode = self.FeedToolbar.GetCurrentDisplayMode();

					if (self.CurrentDisplayMode === SSVC.Utils.Enums.DisplayMode.Standard)
						SSVC.Wrap.Dojo.Require(["dijit/registry"], function(registry)
						{
							SSVC.Wrap.Dojo.Array.forEach(self.getCurrentMessageList(), function(message)
							{
								var messageControl = registry.byId(message.messageId);
								if (messageControl.Classification === "Markup" && messageControl.SnapshotMode)
									messageControl.HideSnapshot();
							});
						});

					if (self.CurrentDisplayMode === SSVC.Utils.Enums.DisplayMode.Review)
						SSVC.Wrap.Dojo.Require(["dijit/registry"], function(registry)
						{
							SSVC.Wrap.Dojo.Array.forEach(self.getCurrentMessageList(), function(message)
							{
								var messageControl = registry.byId(message.messageId);
								if (messageControl.Classification === "Markup" && !messageControl.SnapshotMode)
									messageControl.ShowSnapshot();
							});
						});
				},

				changeMessageSortingMode: function()
				{
					self.CurrentSortingMode = self.FeedToolbar.GetCurrentSortingMode();

					self.SecureMessage.sort(self.CurrentSortingMode);

					if (self.filterArr)
						self.ContextMessageList = SSVC.Message.toMessageArr(self.SecureMessage.itemStructure);
					else
						self.MessageList = SSVC.Message.toMessageArr(self.SecureMessage.itemStructure);

					self.addMessagesToFeed(self.getCurrentMessageList(), true);
				},

				filterMessageButton_OnClick: function()
				{
					this.onClickClearFilter();
				},

				showFilterMessageInfo: function(message, showButton)
				{
					this.FilteringMessageContainer.style.display = "inline";
					this.FilteringMessageText.innerHTML = message;
					this.FilterMessageButton.style.display = (showButton) ? "inline" : "none";
				},

				hideShowFilterMessageInfo: function()
				{
					this.FilteringMessageContainer.style.display = "none";
				},

				showUserInfo: function()
				{
					self.UserControl.UpdateData(
						this.MarkupMessage.userInfo.first_name + " " + this.MarkupMessage.userInfo.last_name,
						this.MarkupMessage.userInfo.telephone,
						this.MarkupMessage.userInfo.company_name,
						this.MarkupMessage.userInfo.email,
						this.MarkupMessage.userInfo.picture);

					//here is hack.
					//because getBoundingClientRect() returns incorrect values for margin applied FeedContainer
					var rect = this.UserNameNode.getBoundingClientRect();
					rect = self.fixBoundingClientRect(rect);

					function arrangeUserInfoConteiner(rect)
					{
						var windowHeight = document.body.clientHeight;

						self.UserInfoContainer.style.left = rect.left + "px";
						self.UserInfoContainer.style.display = "inline";

						if (rect.bottom + self.UserInfoContainer.clientHeight < windowHeight)
							self.UserInfoContainer.style.top = rect.bottom + "px";
						else
							self.UserInfoContainer.style.top = rect.top - self.UserInfoContainer.clientHeight + "px";
					}

					arrangeUserInfoConteiner(rect);

					
				},

				hideUserInfo: function()
				{
					this.HideElement(self.UserInfoContainer);
				},

				showActualDate: function()
				{
					var rect = this.DateTimeNode.getBoundingClientRect();
					rect = self.fixBoundingClientRect(rect);

					self.ActualDateTimeContainer.innerHTML = this.SentDateTimeActual;
					self.ActualDateTimeContainer.style.left = rect.left + "px";
					self.ActualDateTimeContainer.style.top = rect.bottom + "px";
					self.ActualDateTimeContainer.style.display = "inline";
				},

				hideActualDate: function()
				{
					this.HideElement(self.ActualDateTimeContainer);
				},

				fixBoundingClientRect: function(rect)
				{
					var widthFix;
					var heightFix = 0;
					SSVC.Wrap.Dojo.Require(["dijit/registry"], function(registry)
					{
						var widget = registry.byId("MyFeed");
						//margin-left 5% === 0.05
						if (widget)
							widthFix = widget.domNode.offsetWidth * 0.05;
						else
							widthFix = document.body.offsetWidth * 0.05;
					});

					var result = {};
					result.left = rect.left - widthFix;
					result.right = rect.right - widthFix;
					result.top = rect.top - heightFix;
					result.bottom = rect.bottom - heightFix;
					result.width = rect.width;
					result.height = rect.height;

					return result;
				},

				onClickReplyLinkEventHandler: function()
				{
					if ((self.ReplyToolbar.GetVisibility() !== "none") && (self.replyToMessageId === this.id))
					{
						self.ReplyToolbar.SetVisibility("none");
						return;
					}

					self.replyToMessageId = this.id;
					self.ReplyToolbar.SetVisibility("block");
					insertNodeAfter(this.domNode, self.ReplyToolbar.domNode);
				},

				onKeyDownTopMessageMove: function(event)
				{
					if (event.keyCode === 36)
					{
						self.TopMost.moveHome();

						event.preventDefault();
					}

					if (event.keyCode === 33)
					{
						self.TopMost.moveUp();

						event.preventDefault();
					}

					if (event.keyCode === 34)
					{
						self.TopMost.moveDown();

						event.preventDefault();
					}
				},

				onReplyToolbarReplyTextKeyUp: function(event)
				{
					if (event.keyCode === 13)
					{
						if (event.shiftKey)
							return;

						self.onSendReplyEventHandler(true);
					}
				},

				onReplyToolbarReplyButtonClick: function()
				{
					self.onSendReplyEventHandler(true);
				},

				onSendReplyEventHandler: function()
				{
					var currmess = self.getCurrentMessageList().FindDepth("messageId", "childs", self.replyToMessageId);
					var parntmess;
					if (currmess.parentMessageId)
						parntmess = self.getCurrentMessageList().Find("messageId", currmess.parentMessageId);
					else
						parntmess = currmess;

					var secureMessage = self.sendReply(currmess, self.ReplyToolbar.GetMessageText());

					if (secureMessage)
					{
						var newMess = new SSVC.Message(secureMessage, true);
						parntmess.childs.push(newMess);
						resetTextualMessageInputElement(self.ReplyToolbar.taReplyTextNode, 0);
						self.update();
					}
				},
			});

			SSVC.Wrap.Dojo.SetObject("SSVC.UI.Feed.MyFeed", SSVC.Wrap.Dojo.Declare("MyFeed", [Feed, _WidgetBase, _TemplatedMixin],
			{
				currentCommunityId: null,

				constructor: function()
				{
					this.id = "MyFeed";
				},

				postCreate: function()
				{
					this.inherited(arguments);
					this.TitleNode.innerHTML = SSVC.Utils.GetResource("feed_title_base");

					this.MessageContainer.style.height = "calc(100% - 120px)";

					this.own(
						on(this.ResetFeedBtn, "click", this.onResetFeedContextEventHandler));
				},

				update: function()
				{
					this.inherited(arguments);
					this.replyToMessageId = null;
					selectedMessageId = null;

					this.ReplyToolbar.SetVisibility("none");
					this.ReplyToolbar.placeAt(self.ReplyToolbarOuter);
				},

				onChangeFeedContextEventHandler: function(communityId)
				{
					self.currentCommunityId = communityId;
					self.ContextMessageList = self.MessageList.FindAll("communityId", communityId);
					self.filterArr =
						[
							{
								name: "source_id",
								text: communityId,
								condition: "like"
							}
						];

					self.TitleNode.innerHTML = SSVC.Utils.GetResource("feed_title_for") + " " + self.ContextMessageList[0].sourceData.keyed_name;

					self.ResetFeedBtn.style.display = "inline";

					self.FeedToolbar.ftTextArea.disabled = false;
					updateStateOfTextualMessageInputButtonElement(true);

					self.ReplyToolbar.SetVisibility("none");
					self.ReplyToolbar.placeAt(self.ReplyToolbarOuter);

					self.MessageContainer.innerHTML = "";

					self.addMessagesToFeed(self.ContextMessageList, true);
				},

				onResetFeedContextEventHandler: function()
				{
					//Reset title
					self.TitleNode.innerHTML = SSVC.Utils.GetResource("feed_title_base");

					//Hide "Back to normal view" button
					self.ResetFeedBtn.style.display = "none";

					//Disable textarea and button to leave a new comment
					self.FeedToolbar.ftTextArea.disabled = true;
					updateStateOfTextualMessageInputButtonElement(false);

					self.ContextMessageList = null;
					self.filterArr = null;

					//Update feed
					self.update();
				},

				onShowDocumentEventHandler: function(messageId)
				{
					var msgObj = self.SecureMessage.itemStructure.FindDepth("id", "childs", messageId);

					var itemId = msgObj.relatedItm.getID();
					var itemTypeName = msgObj.relatedItm.getType();

					top.aras.uiShowItem(itemTypeName, itemId);
				},

				onSendCommentEventHandler: function()
				{
					var textContent = self.FeedToolbar.GetMessageText();
					if (textContent === "" || textContent === self.FeedToolbar.FeedToolbarInputText || !self.currentCommunityId)
						return;

					var secureMessage = self.sendComment(self.SecureMessage.itemStructure.Find("communityId", self.currentCommunityId).relatedItm, textContent);

					if (secureMessage)
					{
						var newMess = new SSVC.Message(secureMessage, true);
						self.ContextMessageList.unshift(newMess);
						self.MessageList.unshift(newMess);
						resetTextualMessageInputElement(self.FeedToolbar.ftTextArea, 0);

						self.update();
					}
				},

				onClickReplyWithMarkupLinkEventHandler: function()
				{
					self.onDisplayMarkupEventHandler(this.id, this.MarkupMessage.parentMessageId ? this.MarkupMessage.parentMessageId : this.id);
				},

				onDisplayMarkupEventHandler: function(messageId, parentMessageId)
				{
					var msgObj = self.SecureMessage.itemStructure.FindDepth("id", "childs", messageId);
					var itemId = msgObj.relatedItm.getID();
					var itemTypeName = msgObj.relatedItm.getType();

					switch (itemTypeName.toLowerCase())
					{
						case "part":
							//will be imlemented if needed
							break;
						case "simple eco":
							//will be imlemented if needed
							break;
						case "document":
							top.aras.uiShowItem(itemTypeName, itemId);

							//Fill params
							var params = {};
							params.hide = false;
							params.itemId = itemId;

							var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(msgObj.getProperty("view_state", ""));
							params.startPage = xmlDoc.documentElement !== null ? Number(SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.documentElement)) : 1;
							params.messageId = messageId;
							params.readOnly = true;
							params.parentMessageId = parentMessageId ? parentMessageId : null;
							params.viewerMode = SSVC.Utils.Enums.ViewerMode.MarkupReview;

							var res = self.getFirstFoundPdfDocumentFromDocument(itemId);
							if (!res)
								res = self.getFirstFoundImageFromDocument(itemId);
							params.fileId = res.fileId;
							params.fileUrl = res.fileUrl;
							params.fileType = res.fileType;
							params.documentId = itemId;
							params.documentType = "Document";

							localStorage.VC_ViewerParamsObject = JSON.stringify(params);

							var intervalId = setInterval(function()
							{
								var win = top.aras.uiFindWindowEx(itemId);
								if (SSVC.Utils.isNullOrUndefined(win) || SSVC.Utils.isNullOrUndefined(win.aras))
									return;
								clearInterval(intervalId);
							}, 100);
							break;
						case "cad":
							top.aras.uiShowItem(itemTypeName, itemId);

							//Fill params
							params = {};
							params.itemId = itemId;
							params.messageId = messageId;
							params.readOnly = true;
							params.parentMessageId = parentMessageId ? parentMessageId : null;
							params.viewerMode = SSVC.Utils.Enums.ViewerMode.MarkupReview;

							res = self.getFirstFoundHwfDocumentFromCAD(itemId);
							params.fileId = res.fileId;
							params.fileUrl = encodeURIComponent(res.fileUrl);
							params.documentId = itemId;
							params.documentType = "CAD";

							localStorage.VC_ViewerParamsObject = JSON.stringify(params);

							//Open item with viewer
							intervalId = setInterval(function()
							{
								var win = top.aras.uiFindWindowEx(itemId);
								if (SSVC.Utils.isNullOrUndefined(win) || SSVC.Utils.isNullOrUndefined(win.aras))
									return;
								clearInterval(intervalId);
							}, 100);
							break;
					}
				}
			}));

			SSVC.Wrap.Dojo.SetObject("SSVC.UI.Feed.DiscussionFeed", SSVC.Wrap.Dojo.Declare("DiscussionFeed", [Feed, _WidgetBase, _TemplatedMixin],
			{
				instanceDocument: SSVC.Utils.Page.GetInstanceDocument(),

				constructor: function()
				{
					this.id = "DiscussionFeed";

					this.InstanceItemId = this.instanceDocument.itemID;
					var currComnty = SSVC.ArasHelper.SecureMessage.CommunityItem.getByItemId(this.InstanceItemId);

					if (currComnty)
						this.currentCommunityId = currComnty.communityItm.getProperty("id");
					else
						this.currentCommunityId = new SSVC.ArasHelper.SecureMessage.CommunityItem.new(this.instanceDocument.itemTypeID, this.instanceDocument.thisItem.getProperty("config_id")).communityItm.getID();
					this.filterArr =
					[{
						name: "source_id",
						text: this.currentCommunityId,
						condition: "like"
					}];
				},

				postCreate: function()
				{
					this.inherited(arguments);

					this.TitleFeedNode.style.display = "none";

					this.domNode.style.height = "calc(100% - 52px)";
					this.TopContainerNode.style.height = "90px";
					this.MessageContainer.style.height = "calc(100% - 90px)";

					self.FeedToolbar.ftTextArea.disabled = false;
					updateStateOfTextualMessageInputButtonElement(true);
				},

				update: function()
				{
					this.inherited(arguments);
					this.ReplyToolbar.SetVisibility("none");
					this.ReplyToolbar.placeAt(this.ReplyToolbarOuter);
				},

				getMessageContainerHeight: function()
				{
					return document.body.clientHeight - this.ToolbarContainer.clientHeight - 1;
				},

				onSendCommentEventHandler: function()
				{

					function onSuccessSave(secureMessagePar)
					{
						var newMess = new SSVC.Message(secureMessagePar, true);
						if (newMess.parentMessageId)
						{
							var parntmess = self.getCurrentMessageList().Find("messageId", newMess.parentMessageId);
							parntmess.childs.push(newMess);
						}
						else
							self.getCurrentMessageList().unshift(newMess);

						resetTextualMessageInputElement(self.FeedToolbar.ftTextArea, 0);
						self.update();
					}

					self.ReplyToolbar.style.display = "none";
					var textContent = self.FeedToolbar.GetMessageText();
					if (textContent === "" || textContent === self.FeedToolbar.FeedToolbarInputText)
						return;

					var secureMessage;
					if (top.SSVCViewer.IsMarkupPresented())
					{
						secureMessage = top.SSVCViewer.SendComment(textContent, self.currentCommunityId, onSuccessSave);
					}
					else
					{
						secureMessage = self.sendComment(self.instanceDocument.thisItem, textContent);
						if (secureMessage)
							onSuccessSave(secureMessage);
					}

				},

				onClickReplyWithMarkupLinkEventHandler: function()
				{
					self.onDisplayMarkupEventHandler(this.id, this.MarkupMessage.parentMessageId ? this.MarkupMessage.parentMessageId : this.id);
					/*
					//this - caller context - MessageControl
					var itemId = this.MarkupMessage.messageObj.relatedItm.getID();
					var itemTypeName = this.MarkupMessage.messageObj.relatedItm.getType();
					var viewerFrame = top.window.document.getElementById("ViewerFrame").contentWindow;

					switch (itemTypeName.toLowerCase())
					{
						case "part":
							//will be imlemented if needed
							break;
						case "simple eco":
							//will be imlemented if needed
							break;
						case "document":
							top.SSVCViewer.viewerMode = SSVC.Utils.Enums.ViewerMode.View;
							top.SSVCViewer.SetParentMessageId(this.MarkupMessage.parentMessageId ? this.MarkupMessage.parentMessageId : this.id);
							top.SSVCViewer.ClearAllPages();

							var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(this.MarkupMessage.messageObj.getProperty("view_state", ""));
							var pageNumber = xmlDoc.documentElement !== null ? Number(SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.documentElement)) : 1;
							top.SSVCViewer.SetCurrentPage(pageNumber);
							top.SSVCViewer.Unfreeze();

							break;
						case "cad":
							params = {};
							params.itemId = itemId;
							params.readOnly = false;
							params.messageId = this.id;
							params.parentMessageId = this.MarkupMessage.parentMessageId ? this.MarkupMessage.parentMessageId : this.id;
							params.viewerMode = SSVC.Utils.Enums.ViewerMode.View;

							var res = self.getFirstFoundHwfDocumentFromCAD(itemId);
							params.fileId = res.fileId;
							params.fileUrl = encodeURIComponent(res.fileUrl);
							params.fileType = res.fileType;
							params.documentId = itemId;
							params.documentType = "CAD";

							top.VC_ViewerParamsObject = params;

							viewerFrame.location.reload(true);
							break;
					}
					*/
				},

				onDisplayMarkupEventHandler: function(messageId, parentMessageId)
				{
					var msgObj = self.getCurrentMessageList().FindDepth("messageId", "childs", messageId);
					var itemId = msgObj.messageObj.relatedItm.getID();
					var itemTypeName = msgObj.messageObj.relatedItm.getType();
					var viewerFrame = top.document.getElementById("ViewerFrame").contentWindow;

					switch (itemTypeName.toLowerCase())
					{
						case "part":
							//will be imlemented if needed
							break;
						case "simple eco":
							//will be imlemented if needed
							break;
						case "document":
							if (top.SSVCViewer.isViewFrozen)
							{
								if (top.SSVCViewer.viewerMode === SSVC.Utils.Enums.ViewerMode.MarkupCreation)
									if (!top.aras.confirm(SSVC.Utils.GetResource("mark_tb_lose_unsaved_markup")))
										return;

								top.SSVCViewer.viewerMode = SSVC.Utils.Enums.ViewerMode.MarkupReview;

								top.SSVCViewer.Reload();
								top.SSVCViewer.SetParentMessageId(parentMessageId ? parentMessageId : null);
								top.SSVCViewer.UnfreezeAndLoadMarkupFromMessage(messageId);
							}
							else
							{
								top.SSVCViewer.viewerMode = SSVC.Utils.Enums.ViewerMode.MarkupReview;

								top.SSVCViewer.Reload();
								top.SSVCViewer.SetParentMessageId(parentMessageId ? parentMessageId : null);
								top.SSVCViewer.FreezeAndLoadMarkupFromMessage(messageId);
							}
							break;
						case "cad":
							if (top.SSVCViewer.viewerMode === SSVC.Utils.Enums.ViewerMode.MarkupCreation)
								if (!top.aras.confirm(SSVC.Utils.GetResource("mark_tb_lose_unsaved_markup")))
									return;

							top.SSVCViewer.viewerMode = SSVC.Utils.Enums.ViewerMode.MarkupReview;

							top.SSVCViewer.Reload();
							top.SSVCViewer.SetParentMessageId(parentMessageId ? parentMessageId : null);
							top.SSVCViewer.ReloadViewer(messageId);
							break;
					}
				}
			}));

			function updateStateOfTextualMessageInputButtonElement(state)
			{
				var commentButton = self.FeedToolbar.ftAddCommentBtn;
				if (state)
				{
					if (SSVC.Wrap.Dojo.HasClass(commentButton, "MarkupButtonDisabled"))
					{
						SSVC.Wrap.Dojo.RemoveClass(commentButton, "MarkupButtonDisabled");
						SSVC.Wrap.Dojo.AddClass(commentButton, "MarkupButton");
					}
				}
				else
				{
					if (SSVC.Wrap.Dojo.HasClass(commentButton, "MarkupButton"))
					{
						SSVC.Wrap.Dojo.RemoveClass(commentButton, "MarkupButton");
						SSVC.Wrap.Dojo.AddClass(commentButton, "MarkupButtonDisabled");
					}
				}
			}

			function resetTextualMessageInputElement(el, mode)
			{
				switch (mode)
				{
					case 0:
						el.blur();
						el.value = SSVC.Utils.GetResource("feed_tb_def_comment");
						SSVC.Wrap.Dojo.AddClass(el, "notFocusedEmptyInputText");
						break;
					case 1:
						el.value = "";
						SSVC.Wrap.Dojo.RemoveClass(el, "notFocusedEmptyInputText");
						break;
				}
			}

			function insertNodeAfter(referenceNode, newNode)
			{
				referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
			}

			function TopMostMessage(containerNodePar)
			{
				var containerNode = containerNodePar;
				var selectedIndex = 0;

				this.moveUp = function()
				{
					var oldIndex = selectedIndex;

					selectedIndex--;
					while (selectedIndex >= 0)
					{
						if (containerNode.childNodes[selectedIndex].id.indexOf("div") === 0 &&
							containerNode.childNodes[selectedIndex].childNodes[0].style.display === "none" ||
							containerNode.childNodes[selectedIndex].style.display === "none")
							selectedIndex--;
						else
							break;
					}

					if (selectedIndex < 0)
					{
						selectedIndex = oldIndex;
						return;
					}

					if (containerNode.childNodes.length > 0)
						containerNode.childNodes[selectedIndex].scrollIntoView();
				};

				this.moveDown = function()
				{
					var oldIndex = selectedIndex;

					selectedIndex++;
					while (selectedIndex < containerNode.childNodes.length)
					{
						if (containerNode.childNodes[selectedIndex].id.indexOf("div") === 0 &&
							containerNode.childNodes[selectedIndex].childNodes[0].style.display === "none" ||
							containerNode.childNodes[selectedIndex].style.display === "none")
							selectedIndex++;
						else
							break;
					}

					if (selectedIndex >= containerNode.childNodes.length)
					{
						selectedIndex = oldIndex;
						return;
					}

					var oldValue = containerNode.scrollTop;
					containerNode.childNodes[selectedIndex].scrollIntoView();

					if (oldValue === containerNode.scrollTop)
						selectedIndex = oldIndex;
				};

				this.moveHome = function()
				{
					if (containerNode.childNodes.length > 0)
					{
						selectedIndex = 0;
						containerNode.childNodes[selectedIndex].scrollIntoView();
					}
				};
			}
		}));
